﻿using Autofac.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Microsoft.AspNetCore.Builder;
using System;
using System.Diagnostics;
using System.IO;
using Microsoft.AspNetCore.Server.Kestrel.Core;
using System.Collections.Generic;

namespace DCMS.Web
{
	public class Program
	{

		public static void Main(string[] args)
		{
			CreateHostBuilder(args).Build().Run();

		}

		//https://docs.microsoft.com/zh-cn/dotnet/core/tools/dotnet-msbuild
		//MSBuild.exe DCMS.Web.csproj /p:DebugSymbols=false /p:DebugType=None
		//Command 命令行 > UseUrls > json配置文件 > launchSettings applicationUrl
		//dotnet run --urls "http://*:9999"
		//dotnet dcms.dll --urls "http://*:9999"//可以多个也可以一个 多个以;隔开 如 "http://*:9999;http://*:9999"
		public static IHostBuilder CreateHostBuilder(string[] args)
		{
			//var realPath = Directory.GetParent(System.Reflection.Assembly.GetExecutingAssembly().Location).FullName;
#if RELEASE
			 return Host.CreateDefaultBuilder(args)
				.UseServiceProviderFactory(new AutofacServiceProviderFactory())
				.ConfigureWebHostDefaults(webBuilder =>
				{
					webBuilder
						.UseStartup<Startup>();
				});
#else
			return Host.CreateDefaultBuilder(args)
				.UseServiceProviderFactory(new AutofacServiceProviderFactory())
				.ConfigureAppConfiguration(builder =>
				{
					builder.SetBasePath(GetBasePath());
					builder.AddCommandLine(args);
					builder.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);

				})
				.ConfigureWebHostDefaults(webBuilder =>
				{
					webBuilder
					.UseStartup<Startup>()
					.UseKestrel(SetHost);
				});
#endif





		}

		//dotnet dev-certs https -ep E:/Git/DCMS.Studio.Core/DCMS.Core/DCMS.Web/certificate.pfx -p racing.1
		private static string GetBasePath()
		{
			var environment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
			var isDevelopment = environment == Environments.Development;
			if (isDevelopment)
			{
				return Directory.GetCurrentDirectory();
			}
			using var processModule = Process.GetCurrentProcess().MainModule;
			return Path.GetDirectoryName(processModule?.FileName);
		}


		/// <summary>
		/// 配置Kestrel
		/// </summary>
		/// <param name="options"></param>
		private static void SetHost(KestrelServerOptions options)
		{
			var configuration = (IConfiguration)options.ApplicationServices.GetService(typeof(IConfiguration));
			var host = configuration.GetSection("RafHost").Get<KHost>();//依据Host类反序列化appsettings.json中指定节点
			foreach (var endpointKvp in host.Endpoints)
			{
				var endpointName = endpointKvp.Key;
				var endpoint = endpointKvp.Value;//获取appsettings.json的相关配置信息
				if (!endpoint.IsEnabled)
				{
					continue;
				}

				var address = System.Net.IPAddress.Parse(endpoint.Address);
				options.Listen(address, endpoint.Port, opt =>
				{
					if (endpoint.Certificate != null)//证书不为空使用UserHttps
					{
						switch (endpoint.Certificate.Source)
						{
							case "File":
							   opt.Protocols = HttpProtocols.Http1;
								opt.UseHttps(endpoint.Certificate.Path, endpoint.Certificate.Password);
								break;
							default:
								throw new NotImplementedException($"文件 {endpoint.Certificate.Source}还没有实现");
						}
						//opt.UseConnectionLogging();
					}
				});

				options.UseSystemd();
			}
		}
	}


	/// <summary>
	/// 待反序列化节点
	/// </summary>
	public class KHost
	{
		/// <summary>
		/// appsettings.json字典
		/// </summary>
		public Dictionary<string, Endpoint> Endpoints { get; set; }
	}

	/// <summary>
	/// 终结点
	/// </summary>
	public class Endpoint
	{
		/// <summary>
		/// 是否启用
		/// </summary>
		public bool IsEnabled { get; set; }

		/// <summary>
		/// ip地址
		/// </summary>
		public string Address { get; set; }

		/// <summary>
		/// 端口号
		/// </summary>
		public int Port { get; set; }

		/// <summary>
		/// 证书
		/// </summary>
		public Certificate Certificate { get; set; }
	}

	/// <summary>
	/// 证书类
	/// </summary>
	public class Certificate
	{
		/// <summary>
		/// 源
		/// </summary>
		public string Source { get; set; }

		/// <summary>
		/// 证书路径()
		/// </summary>
		public string Path { get; set; }

		/// <summary>
		/// 证书密钥
		/// </summary>
		public string Password { get; set; }
	}
}
